#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

void PrintSig(const sigset_t &s)
{
    cout << "pending : ";
    for (int i = 31; i > 0; i--)
    {
        if (sigismember(&s, i))
        {
            cout << '1';
        }
        else
        {
            cout << '0';
        }
    }
    cout << endl;
}

void handler(int signo)
{
    sigset_t s;
    sigemptyset(&s);
    int n = sigpending(&s);
    if (n < 0)
    {
        cout << "抵达中： sigpending error, error string : " << strerror(errno) << endl;
    }
    cout << "signo : " << signo << endl;
}

int main()
{
    signal(2, handler);
    // 阻塞2号信号
    sigset_t s, olds;
    sigemptyset(&s);
    sigemptyset(&olds);
    sigaddset(&s, 2); // 上述操作发生在栈上，没有在内核中，只是在栈上定义了一个结构体变量

    int n = sigprocmask(SIG_SETMASK, &s, &olds);
    if (n < 0)
    {
        cout << "sigprocmask error, error string : " << strerror(errno) << endl;
    }
    cout << "pid : " << getpid() << endl;
    // 不断打印当前进程的pending表，因为2号信号被阻塞，所以2号信号一定不会被抵达处理，一直被保存在pending位图中
    int cnt = 0;
    while (true)
    {
        sigset_t t;
        sigemptyset(&t);
        n = sigpending(&t);
        if (n < 0)
        {
            cout << "sigpending error, error string : " << strerror(errno) << endl;
        }
        PrintSig(t);
        sleep(1);
        cnt++;
        if (cnt == 20)
        {
            n = sigprocmask(SIG_UNBLOCK, &s, &olds);
            cout << "解除对2号信号的阻塞" << endl;
            if (n < 0)
            {
                cout << "sigprocmask error, error string : " << strerror(errno) << endl;
            }
        }
    }
    return 0;
}

// void handler(int signo)
// {
//     unsigned int ret = alarm(5);
//     cout << "剩余时间 : " << ret << endl;
// }

// int main()
// {
//     signal(SIGALRM, handler);
//     alarm(100);
//     int cnt  = 0;
//     while(true)
//     {
//         cout << "pid : " << getpid() << endl;
//         sleep(1);
//     }
//     return 0;
// }

// int main()
// {
//     pid_t id = fork();
//     if(id == 0)
//     {
//         //child
//         int cnt = 10;
//         while(cnt--)
//         {
//             cout << "cnt :" << cnt << ", pid :" << getpid() << endl;
//             sleep(1);
//         }
//         abort();
//     }
//     int status;
//     pid_t rid = waitpid(id, &status, 0);
//     cout << "exit code :" << WEXITSTATUS(status) << ", exit signal :" << (status & 0x7f) << endl;
// }

// int main(int argc, char* argv[])
// {
//     if(argc != 3)
//     {
//         cout << "Useage: " << argv[0] << " -signo pid" << endl;
//     }
//     int signo = stoi(argv[1] + 1);
//     int pid = stoi(argv[2]);
//     int ret = kill(pid, signo);
//     if(ret < 0)
//     {
//         cout << "kill error, errno : " << errno << ", error string : " << strerror(errno) << endl;
//     }
//     return 0;
// }

// void handler(int signo)
// {
//     cout << "get a signal, signo : " << signo << endl;
//     exit(0);
// }

// int main()
// {
//     signal(2, handler);
//     signal(3, handler);
//     while(true)
//     {
//         cout << "wait..., pid : " << getpid() << endl;
//         sleep(1);
//     }
//     return 0;
// }